package ext.tianma.part.util.emailService;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFCell;

import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;

import ext.com.iba.IBAUtil;
import ext.generic.erp.common.CommonUtil;
import ext.tianma.bom.service.SelectPartService;
import ext.tianma.bom.util.QueryUtil;
import ext.tianma.bom.util.StringUtil;
import ext.tianma.part.forms.TMTypeUtil;
import ext.tianma.util.GetSuperior;
import ext.tianma.util.IbaAttributeUtil;
import ext.tianma.util.PropertiesUtil;
import wt.doc.WTDocument;
import wt.fc.ObjectReference;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.fc.WTObject;
import wt.fc.collections.WTArrayList;
import wt.mail.EMailMessage;
import wt.method.RemoteAccess;
import wt.org.WTUser;
import wt.part.WTPart;
import wt.pom.PersistenceException;
import wt.query.AttributeRange;
import wt.query.QueryException;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.type.ClientTypedUtility;
import wt.type.TypeDefinitionForeignKey;
import wt.type.TypeDefinitionReference;
import wt.type.Typed;
import wt.util.WTException;
import wt.vc.config.LatestConfigSpec;
import wt.vc.views.View;
import wt.vc.views.ViewHelper;

/**
 * 零部件封样节点提醒,用于零件承认邮件提醒,用于图纸生效邮件提醒
 * @author laichao_sun
 *
 */
public class SealedSampleEmail implements RemoteAccess, Serializable {

	private static final long serialVersionUID = 3265887452892197956L;
	public static String path = "/ptc/Windchill/codebase/ext/tianma/part/config/sealedSampleEmail.xls";
	public static final String RawMaterial = "cn.tianma.RawMaterial";// 原材料
	public static final String discardState = "OBSOLESCENCE";// 废弃状态
	public static final String D_VIEW = "Design";// 视图
	public static String configFilePath = "codebase" + File.separator + "ext" + File.separator + "tianma"
			+ File.separator + "cfg" + File.separator + "TianmaPro.properties";
	
	/**
	 * 用于提醒系统管理人员,提示今天部件封样承认邮件提醒已执行
	 */
	public static void sealedEmailToManagers() {
		PropertiesUtil ut = new PropertiesUtil(configFilePath);
		String emailAddr = ut.getValueByKey("Sealed_Email_Managers");

		if (StringUtil.isNullOrEmpty(emailAddr)) {
			System.out.println("SLC ==没有获取到今天部件封样样品承认邮件提醒的通知者的邮箱==>");
			return;
		} else {
			System.out.println("SLC ==开始通知管理者==>");
			try {
				System.out.println("SLC ==通知者的邮箱==>"+emailAddr);
				// 邮件内容
				StringBuffer body = new StringBuffer();
				String content = "今天时间为 "+CommonUtil.getCurrentTime()+" 的时候,部件封样样品承认邮件提醒已执行! ";
				body.append(content);
				String[] emailSendTo = "".equals(emailAddr) || emailAddr == null ? null : emailAddr.split(";");// 2、why？
				EMailMessage email = EMailMessage.newEMailMessage();
				email.addEmailAddress(emailSendTo);
				// 邮件主题
				StringBuffer title = new StringBuffer();
				String titleStr = "部件封样样品承认邮件提醒";
				title.append(titleStr);
				email.setSubject(title.toString());
				email.setMultipartSubtype("text/html;charset=\"UTF8\"");
				email.addPart(body.toString(), "text/html;charset=\"UTF8\"");
				email.send(false);
			} catch (WTException e) {
				e.printStackTrace();
			}
			System.out.println("SLC ==结束通知管理者==>");
		}
	}
	
	/**
	 * 用于零件承认邮件提醒,用于图纸生效邮件提醒, 接受邮件的人员为创建者及上一级主管 邮件内容为部件料号, 材料型号
	 */
	public static void sealedEmail() {
		
		PropertiesUtil ut = new PropertiesUtil(configFilePath);
		String SealedSampleEmail_time = ut.getValueByKey("SealedSampleEmail_time");
		String time = "";
		String[] times = SealedSampleEmail_time.split(";");
		for (int i = 0; i < times.length; i++) {
			time = times[i];
			getPart(time);
		}
		
	}
	
	//根据配置文件查询部件
	private static void getPart(String time) {
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			QuerySpec qs = new QuerySpec(WTPart.class);
			qs.setAdvancedQueryEnabled(true);
			// 类型
			TypeDefinitionReference clientType = ClientTypedUtility.getTypeDefinitionReference(RawMaterial);
			SearchCondition sc = new SearchCondition(WTPart.class,
					Typed.TYPE_DEFINITION_REFERENCE + "." + TypeDefinitionReference.KEY + "."
							+ TypeDefinitionForeignKey.BRANCH_ID,
					SearchCondition.EQUAL, clientType.getKey().getBranchId());
			qs.appendWhere(sc, new int[] { 0 });
			qs.appendAnd();
			// 视图
			View view = ViewHelper.service.getView(D_VIEW);
			SearchCondition sc1 = new SearchCondition(WTPart.class, "view.key.id", SearchCondition.EQUAL,
					view.getPersistInfo().getObjectIdentifier().getId());
			qs.appendWhere(sc1);
			qs.appendAnd();
			// 状态
			SearchCondition sc2 = new SearchCondition(WTPart.class, WTPart.LIFE_CYCLE_STATE, SearchCondition.NOT_EQUAL,
					discardState);
			qs.appendWhere(sc2, new int[] { 0 });
			qs.appendAnd();
			// 时间段
			// 开始时间2019-07-15 00:00:00
			// Date startDate =new Date();
			Date startDate = format.parse(getTime(time, "start"));
			// 结束时间2019-07-16 00:00:00
			// Date endDate =new Date();
			Date endDate = format.parse(getTime(time, "end"));

			Timestamp beginDate = new Timestamp(startDate.getTime());
			Timestamp finshDate = new Timestamp(endDate.getTime());
			AttributeRange range = new AttributeRange(beginDate, finshDate);
			SearchCondition sc3 = new SearchCondition(WTPart.class, "thePersistInfo.modifyStamp", true, range);
			qs.appendWhere(sc3);
			qs.appendAnd();
			qs.appendWhere(QueryUtil.getIBASearchCondition(WTPart.class, "isSealedEmail", time,SearchCondition.EQUAL));
			qs.appendOr();
			qs.appendWhere(QueryUtil.getIBASearchCondition(WTPart.class, "isDrawingEmail", time,SearchCondition.EQUAL));

			QueryResult qr = PersistenceHelper.manager.find(qs);
			qr = new LatestConfigSpec().process(qr);
			while (qr.hasMoreElements()) {
				WTPart part = (WTPart) qr.nextElement();
				System.out.println("SLC..............result:" + part.getNumber() + " | " + part.getViewName());
				
				//判断部件标识,发送邮件
				String identification2 = IbaAttributeUtil.getAttributeValue(part, "isSealedEmail");

				System.out.println("SLC ==部件的封样提醒内部时间(标识)==>" + identification2+" | "+part.getNumber()+" | "+part.getViewName());
				
				String isDrawing = IbaAttributeUtil.getAttributeValue(part, "isDrawingEmail");
				System.out.println("SLC ==部件的图纸生效提醒内部时间(标识)==>" + isDrawing+" | "+part.getNumber()+" | "+part.getViewName());
				// 封样邮件提醒
				if (time.equals(identification2)) {
					emailToPeople(part,"部件样品承认邮件提醒","样品承认");
				}
				//图纸生效提醒
				if (time.equals(isDrawing)) {
					emailToPeople(part,"部件图纸生效提醒","图纸生效");
				}
			}
		}catch (QueryException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
	// 发送邮件内容给创建者及上级领导
	private static void emailToPeople(WTPart part,String titleStr,String string) {
		System.out.println("SLC ==开始发送邮件==>");
		try {
			// 创建者的名字
			String name = part.getCreatorName();
			System.out.println("创建者:"+name);
			WTUser user = getUserByName(name);

			String emailAddr = user.getEMail();// 电子邮件
			System.out.println("SLC ==emailAddr======" + emailAddr);
			// 邮件内容
			String content = content(part,string);
			//String titleStr = "部件样品承认邮件提醒";
			// 发送邮件
			boolean bol = sendEmail(emailAddr, content, titleStr);
			if (bol&&"部件样品承认邮件提醒".equals(titleStr)) {
				IBAUtil.forceSetIBAValue(part, "isSealedEmail", "");
				System.out.println("SLC ==邮件发送给创建者成功==>");
			}else if(bol&&"部件图纸生效提醒".equals(titleStr)) {
				IBAUtil.forceSetIBAValue(part, "isDrawingEmail", "");
				System.out.println("SLC ==邮件发送给创建者成功==>");
			}

			// 创建者的上一级主管
			String name2 = GetSuperior.getSuperior(name);
			System.out.println("上级领导的名字:" + name2);

			WTUser user2 = getUserByName(name2);
			String emailAddr2 = user2.getEMail();// 电子邮件
			System.out.println("SLC ==emailAddr2======" + emailAddr);
			// 发送邮件
			boolean bol2 = sendEmail(emailAddr2, content, titleStr);
			if (bol2) {
				System.out.println("SLC ==邮件发送给主管成功==>");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/***
	 * 根据用户名称获取user
	 * 
	 * @param name
	 * @return
	 * @throws WTException
	 */
	@SuppressWarnings("rawtypes")
	private static WTUser getUserByName(String name) throws WTException {
		WTUser user = null;
		QuerySpec qs = new QuerySpec(WTUser.class);
		SearchCondition sc = new SearchCondition(WTUser.class, WTUser.NAME, "=", name);
		qs.appendWhere(sc);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements()) {
			user = (WTUser) qr.nextElement();
		}
		return user;
	}

	// 拼接邮件内容
	private static String content(WTPart part,String string) throws PersistenceException, WTException {

		String infoPage = "";
		String number = "";
		String url = "";
		String partDrawingNumber = "";
		String content = "";

		number = part.getNumber();

		partDrawingNumber = IbaAttributeUtil.getAttributeValue(part, "partDrawingNumber");
		System.out.println("材料型号:" + partDrawingNumber);

		url = SelectPartService.generateInfoPageURL(part);
		infoPage = "<a target='_blank' href='" + url + "'>" + number + "</a>";

		content = "零部件编号:" + infoPage + ",材料型号:" + partDrawingNumber + ",该部件需要"+string+",请处理!";

		System.out.println("邮件内容:" + content);
		return content;
	}

	/**
	 * 发送邮件
	 * 
	 * @param userName
	 * @param content
	 * @param titleStr
	 * @return
	 */
	public static boolean sendEmail(String emailAddr, String content, String titleStr) {
		try {
			System.out.println("emailAddr======" + emailAddr);
			// 邮件内容
			StringBuffer body = new StringBuffer();
			body.append(content);
			String[] emailSendTo = "".equals(emailAddr) || emailAddr == null ? null : emailAddr.split(";");// 2、why？
			EMailMessage email = EMailMessage.newEMailMessage();
			email.addEmailAddress(emailSendTo);
			// 邮件主题
			StringBuffer title = new StringBuffer();
			title.append(titleStr);
			email.setSubject(title.toString());
			email.setMultipartSubtype("text/html;charset=\"UTF8\"");
			email.addPart(body.toString(), "text/html;charset=\"UTF8\"");
			email.send(false);
			return true;
		} catch (WTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}

	}
	
	// 根据查询时间获取条件查询时间
	private static String getTime(String num, String string) {
			try {
				// 小时数
				int n = Integer.parseInt(num);
				// 获取当前时间
				String nowTime = CommonUtil.getCurrentTime();

				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

				Date date = sdf.parse(nowTime);

				Calendar calendar = Calendar.getInstance();

				calendar.setTime(date);
				calendar.set(Calendar.HOUR_OF_DAY, 0);
				calendar.set(Calendar.MINUTE, 0);
				calendar.set(Calendar.SECOND, 0);

				System.out.println("产品方法里面的时间方法:" + nowTime);

				// 输出当前系统时间;
				System.out.println("当前系统时间: " + sdf.format(calendar.getTime()));

				// add()增加日期，以天为单位（Calendar封装了很多静态的操作时间的单位）
				// 增加7天，负数则为减少天数
				if ("start".equals(string)) {
					calendar.add(Calendar.HOUR_OF_DAY, -n);
				} else if ("end".equals(string)) {
					calendar.add(Calendar.HOUR_OF_DAY, -n + 24);
				}

				// 输出减少n个小时后的时间
				System.out.println("减少"+n+"小时后的时间: " + sdf.format(calendar.getTime()));

				String time = sdf.format(calendar.getTime());

				return time;
			} catch (Exception e) {
				e.printStackTrace();
			}
			return "";
		}

	/*
	 * 根据配置文件给予标识 用于零部件申请流程走完之后给予邮件提醒标识
	 * 
	 */
	public static boolean isSealedEmail(WTObject object) {
		Workbook we = null;
		InputStream in = null;
		try {
			System.out.println("SLC ==开始设置零部件封样节点提醒标识==>");
			WTPart part = null;
			if (object instanceof WTPart) {
				part = (WTPart) object;
				System.out.println("SLC ==零件的料号==>" + part.getNumber());
				
				in = new FileInputStream(path);
				we = WorkbookFactory.create(in);
				if (null == path || path.equals("")) {
					throw new WTException("没有获取到零部件封样节点提醒的配置路径，请检查!");
				}
				if (null == in || null == we) {
					throw new WTException("没有获取到零部件封样节点提醒的配置路径，请检查!");
				}
				
				boolean flag = getCode(we.getSheetAt(0),part);
				
				return flag;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			close(in);
		}
		return false;
	}
	
	// 为部件设置标识
	private static boolean getCode(Sheet sheet, WTPart part) {
		try {
			// 零部件的编号
			String number = part.getNumber();
			// 物料类别代码
			String num = number.substring(0, 3);
			// 物料名称
			String name = part.getName();
			
			for (int i = 1; i < sheet.getLastRowNum() + 1; i++) {
				Row row = sheet.getRow(i);
				//料类别代码
				String temp = getCellValue(row.getCell(0)).trim();
				if (null == temp || temp.equals("")) {
					continue;
				} else {
					if (num.equals(temp)) {
						String temp2 = getCellValue(row.getCell(1)).trim();
						if(name.equals(temp2)) {
							//设置图纸生效的标识
							String temp5 = getCellValue(row.getCell(4)).trim();
							if (!(temp5.isEmpty() || "".equals(temp5))) {
								Hashtable<String, String> values = new Hashtable<String, String>();
								values = addToHashtable(values, "isDrawingEmail", temp5);
								IBAUtil.setSoftTypeIBAValues(part, values);
								PersistenceHelper.manager.refresh(part);
							}
							//是否需要零件承认
							String partRecognize = IbaAttributeUtil.getAttributeValue(part,"partRecognize");
							String temp3 = getCellValue(row.getCell(2)).trim();
							if(partRecognize.equals(temp3)) {
								String temp4 = getCellValue(row.getCell(3)).trim();
								Hashtable<String, String> values = new Hashtable<String, String>();
								values = addToHashtable(values, "isSealedEmail", temp4);
								IBAUtil.setSoftTypeIBAValues(part, values);
								PersistenceHelper.manager.refresh(part);
							}
							return true;
						}
					}
				}

			}	
		}catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/*
	 * 用于样品承认流程中清除零部件的标识
	 */
	public static boolean clearIdentification(WTObject object) {
		System.out.println("SLC =======开始清除零部件样品承认提醒标识==>");
		try {
			WTPart part = null;
			if (object instanceof WTPart) {
				part = (WTPart) object;
				System.out.println("部件的料号及视图:" + part.getNumber() + " | " + part.getViewName());
				if (TMTypeUtil.isRawMaterial(part)) {
					IBAUtil.forceSetIBAValue(part, "isSealedEmail", "");
					return true;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/*
	 * 此类用于根据文件关联部件,清除零件的标识 用于生效图纸流程中清除零部件的标识
	 */
	public static boolean clearIdentification2(WTObject object) {
		System.out.println("SLC =======开始清除零部件图纸生效提醒标识==>");
		try {
			WTDocument doc = null;
			WTArrayList list = new WTArrayList();
			if (object instanceof WTDocument) {
				doc = (WTDocument) object;
				String type = ClientTypedUtility.getTypeIdentifier(doc).getTypename();
				if (!type.contains("cn.tianma.ControlDocument")) {
					return false;
				}
				// 获取部件
				list = getAllRelatedParts(doc);
				System.out.println("部件的个数:" + list.size());

				for (int j = 0; j < list.size(); j++) {
					ObjectReference partref = (ObjectReference) list.get(j);
					Object partobj = partref.getObject();
					WTPart part = (WTPart) partobj;
					if (!TMTypeUtil.isRawMaterial(part)) {
						continue;
					}
					IBAUtil.forceSetIBAValue(part, "isDrawingEmail", "");
				}
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 通过文档获取所关联的所有零部件
	 * 
	 * @param doc
	 * @return
	 * @throws WTException
	 */
	private static WTArrayList getAllRelatedParts(WTDocument doc) throws WTException {
		WTArrayList allPart = new WTArrayList();

		// 获取当前文档所关联的所有零部件
		QueryResult refPartQR = ext.com.core.CoreUtil.getAssociatedParts(doc);

		while (refPartQR.hasMoreElements()) {
			Object refObj = refPartQR.nextElement();

			if (refObj != null && refObj instanceof WTPart) {
				WTPart part = (WTPart) refObj;

				System.out.println("关联部件的编号:" + part.getNumber() + " | " + part.getViewName());
				// 将文档关联的零部件加入List
				allPart.add(part);
			}
		}

		return allPart;
	}
	
	/**
	 * 实现Hashtable添加数据时不会出现空指针异常
	 * 
	 * @param hashtable
	 * @param key
	 * @param value
	 * @return
	 */
	private static Hashtable<String, String> addToHashtable(Hashtable<String, String> hashtable, String key,
			String value) {
		if (key == null && hashtable != null) {
			return hashtable;
		}

		if (value == null && hashtable != null) {
			return hashtable;
		}

		if (key == null && hashtable == null) {
			return new Hashtable<String, String>();
		}

		if (value == null && hashtable == null) {
			return new Hashtable<String, String>();
		}

		if (hashtable == null) {
			hashtable = new Hashtable<String, String>();
		}
		hashtable.put(key, value);

		return hashtable;
	}
	
	/**
	 * 获取单元格中的信息
	 * 
	 * @param cell 单元格
	 * @return 主要参数信息
	 * @throws Exception
	 */
	public static String getCellValue(Cell cell) throws WTException {
		String value = "";
		try {
			if (null == cell) {
				return "";
			}
			switch (cell.getCellType()) {
			case XSSFCell.CELL_TYPE_NUMERIC:
				value = Double.toString(cell.getNumericCellValue());
				break;
			case XSSFCell.CELL_TYPE_STRING:
				value = cell.getStringCellValue();
				break;
			case XSSFCell.CELL_TYPE_BLANK:
				value = "";
				break;
			case XSSFCell.CELL_TYPE_BOOLEAN:
				value = Boolean.toString(cell.getBooleanCellValue());
				break;
			case XSSFCell.CELL_TYPE_FORMULA:
				try {
					value = String.valueOf(cell.getNumericCellValue());
				} catch (Exception e) {
					value = cell.getStringCellValue();
				}
				break;
			default:
				break;
			}
		} catch (Exception e) {
		}

		return value.trim();
	}
	
	/**
	 * 关闭资源
	 * @param closeable
	 */
	public static void close(Closeable closeable) {
		try {
			if (closeable != null) {
				closeable.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}
